package com.lagou.handler;

import com.alibaba.fastjson.JSONObject;
import com.lagou.service.pojo.RpcRequest;
import io.netty.channel.ChannelHandlerContext;
import io.netty.channel.ChannelInboundHandlerAdapter;
import org.springframework.beans.BeansException;
import org.springframework.cglib.reflect.FastClass;
import org.springframework.cglib.reflect.FastMethod;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationContextAware;
import org.springframework.stereotype.Component;

/**
 * @author Administrator
 * @version 1.0
 * @date 2020/7/4 8:18
 */
@Component
public class UserServerHandler extends ChannelInboundHandlerAdapter implements ApplicationContextAware {

    //获取到applicationCOntext
    private static  ApplicationContext applicationContexts;
    @Override
    public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
        UserServerHandler.applicationContexts = applicationContext;
    }

    /**
     * 当客户端读取数据时，该方法会被调用
     * @param ctx
     * @param msg
     * @throws Exception
     */
    @Override
    public void channelRead(ChannelHandlerContext ctx, Object msg) throws Exception {
      //服务端收到参数可以利用反射或者动态代理调用UserServiceImpl 最终向客户端返回
        System.out.println("服务端获取到的数据内容");

            RpcRequest rpcRequest = (RpcRequest)msg;
            System.out.println("客户端传递过来的是RpcRequest");
            System.out.println(JSONObject.toJSONString(msg));
            //利用反射获取到请求过来的参数实例对象
            //使用class.forName进行加载class文件
            Class<?> clazz = Class.forName(rpcRequest.getClassName());
            Object serviceBean = applicationContexts.getBean(clazz);
            Class<?> serviceClass = serviceBean.getClass();
            String methodName = rpcRequest.getMethodName();

            Class<?>[] parameterTypes = rpcRequest.getParameterTypes();
            Object[] parameters = rpcRequest.getParameters();

            FastClass fastClass = FastClass.create(serviceClass);
            FastMethod fastMethod = fastClass.getMethod(methodName,parameterTypes);

            fastMethod.invoke(serviceBean,parameters);

            ctx.writeAndFlush("SUCCESS");

    }


}
